- R-Shiny is a series of packages for creating interactive, web-based apps, which can run locally or as a stand alone website.
9/28/2020
CSS and JavaScriptthe UI waits for us to do something (input),
this input is passed to the server, which then performs actions based on the input, and populates an output within the UI
This happens in a loop extremely quickly
library(shiny)
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bin_output", label = "Number of bins:", min = 1,max = 50, value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "hist_out")
)
)
)
server <- function(input, output) {
output$hist_out <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bin_output + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui = ui, server = server)
shinyApp(ui = ui, server = server) is what actually runs the server and UIfluidPage defines the base UI( there are other ways to do this for more complicated apps, but we won’t be covering them)library(shiny)
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins", label = "Number of bins:", min = 1,max = 50, value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
sidebarLayout is composed of a sidebarPanel and a mainPanel. See the documentation for sidebarLayout for more info), vs ) , - help mitigate this.sliderInput(inputId = "bins", label = "Number of bins:", min = 1,max = 50, value = 30) plotOutput(outputId = "distPlot")
server function, and similarly set/get each outputserver <- function(input, output, session) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
input and ouptut must be specified as arguments, and are almost always the only arguments for the function.session argument is optional, and can some times be required for more complicated apps. the session is a way to store information about the specific run of an app, ie so it can be saved and loaded again.input is a list where each element corresponds to an inputID within the UI. The value within each inputID corresponds to the specific UI element its associated with## from UI sliderInput(inputId = "bins", label = "Number of bins:", min = 1,max = 50, value = 30) ## from server bins <- seq(min(x), max(x), length.out = input$bins + 1)
output argument contains “empty” outputIDs, that are connected to the outputs in UIrender* objectoutput$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
server functions is the use of renderPlot, which is how we generate the plot associated with the plotOutput defined in the UI{}. This makes it much easier to write server code.plotOutput, server :renderPlot - display a plottableOutput, server :renderTable - display a data.frametextOutput, server :renderText - display plain textdataTableOutput, server: renderDataTable - display an interactive viewer for a data.framelibrary(shiny)
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins", label = "Number of bins:", min = 1,max = 50, value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui = ui, server = server)
Rscript. This is nothing more than a text file with a .R extension. We won’t be able to run code interactively like a notebooksidebarLayoutsidebarLayout UI we have seen is a basic, preconfigured way for laying out appsfluidRow and columnssidebarLayoutcolumn will create a create a vertical subregion of the UIcolumn has the parameter width which corresponds to how wide a column is.column we must use at least 2 or more columns, and the total width must sum to 12columnsui <- fluidPage(
titlePanel('Example Shiny App'),
column(5,
dataTableOutput(outputId = 'table'),
),
column(2),
column(5,
actionButton(inputId = 'plot_button',label = 'Draw Plot' ),
plotOutput(outputId = 'scatter'),
selectizeInput(inputId = 'flower_to_plot',
label = 'Pick a flower to visualiz',
selected = "setosa", choices = c("setosa", "versicolor", "virginica")),
sliderInput(inputId = 'point_size', label = "Choose a point size",
value = 3, min = 1, max = 10)
)
)
fluidRow function defines a horizontal subregion of the plotcolumn, fluidRows do not have a predefined size; the size of the row is determined by the largest ui element within the rowfluidRow exampleui <- fluidPage(
titlePanel('Example Shiny App'),
fluidRow(
dataTableOutput(outputId = 'table'),
),
fluidRow(),
fluidRow(
actionButton(inputId = 'plot_button',label = 'Draw Plot' ),
plotOutput(outputId = 'scatter'),
selectizeInput(inputId = 'flower_to_plot',
label = 'Pick a flower to visualiz',
selected = "setosa", choices = c("setosa", "versicolor", "virginica")),
sliderInput(inputId = 'point_size', label = "Choose a point size",
value = 3, min = 1, max = 10)
)
)
fluidRow examplefluidRow and columncolumn inside fluidRow:fluidPage(
fluidRow(
column(6,
...
),
column(6,
...
)
),
fluidRow(
column(4,
...
),
column(4,
...
),
column(4,
...
)
),
)
column also apply when it is called within fluidRowfluidRow and columnfluidRow inside column:fluidPage(
column(8
fluidRow(
...
),
fluidRow(
...
)
),
column(6
fluidRow(
...
),
fluidRow(
...
),
fluidRow(
...
)
),
)
render... portion of server codeui <- fluidPage(
titlePanel('Example Shiny App'),
column(5,
dataTableOutput(outputId = 'table'),
),
column(2),
column(5,
actionButton(inputId = 'plot_button',label = 'Draw Plot' ),
plotOutput(outputId = 'scatter'),
selectizeInput(inputId = 'flower_to_plot',
label = 'Pick a flower to visualiz',
selected = "setosa", choices = c("setosa", "versicolor", "virginica")),
sliderInput(inputId = 'point_size', label = "Choose a point size",
value = 3, min = 1, max = 10)
)
)
server <- function(input, output) {
observeEvent(input$plot_button, {
output$scatter <- renderPlot({
data_to_plot <- iris %>%
filter(Species == input$flower_to_plot)
ggplot(data= data_to_plot) +
geom_point(aes(x=Petal.Width, y= Petal.Length), size = input$point_size) +
theme_minimal()
})
})
observeEvent function will only execute code once a reactive input value has been filled. Here we use it for the button, but it can be used for any reactive input.input values inside a renderFunction.render... call, you can use the isolate function to access itserver <- function(input, output) {
k <- isolate(input$flower_to_plot)
cat(k, file = stderr())
observeEvent(input$plot_button, {
output$scatter <- renderPlot({
data_to_plot <- iris %>%
filter(Species == input$flower_to_plot)
ggplot(data= data_to_plot) +
geom_point(aes(x=Petal.Width, y= Petal.Length), size = input$point_size) +
theme_minimal()
})
})
}
plotlyplotly is fairly different from ggplot, and is closer to ggpubrlibrary(plotly)
## Loading required package: ggplot2
## ## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2': ## ## last_plot
## The following object is masked from 'package:stats': ## ## filter
## The following object is masked from 'package:graphics': ## ## layout
plot_ly(iris, x = ~Sepal.Width, y = ~Sepal.Length, type = 'scatter', mode = 'markers')
ui <- fluidPage(
selectInput("choice", "Choose", choices = names(iris), selected = 'Petal.Width'),
plotlyOutput("graph")
)
server <- function(input, output, session){
output$graph <- renderPlotly({
plot_ly(iris, x = ~get(input$choice), y = ~Sepal.Length, z= ~Sepal.Width, mode = 'markers')
})
}
shinyApp(ui, server)
plotlyOutput <> renderPlotly UI-server comboget function lets you get a variable named that is stored inside another variablecat(<varname>, file = stderr())